package com.cmz.common.api.enums;

import com.cmz.common.providers.ProviderFactory;
import com.cmz.common.utils.I18nUtils;
import com.cmz.common.utils.SpringUtils;

import java.util.Locale;

/**
 * 错误编码枚举接口：成功响应为12位零
 *
 * 错误码沿用响应码的编码规则，采用4段12位的编码方式：
 * 第一段：长度为1位，用于错误的定向（确定错误处理大方向）
 *        X 技术类错误：指错误在于技术方面因素，或者问题需要由技术人员来检查或解决，一般倾向于硬件或者是系统软件的原因
 *        Y 业务类错误：指错误在于业务方面因素，或者问题需要由业务人员或用户来检查或处理，一般倾向于人为原因，亦可称应用类错误
 *        Z 第三方错误：指错误在于第三方系统（外来/外购产品或中间件，或者外部连接的非本行系统），一般可向第三方支持人员提请排查和解决
 * 第二段：长度为2位，用于错误的定性（确定错误性质或严重程度），指明错误的二级分类，例如密码相关、权限限额、流控等
 *        密码与认证	    PW（Password）
 *        数量与限额	    AL（Amount Limitation）
 *        权限控制	    AC（Authority Control）
 *        信息滥缺	    DC（Data Context）
 *        内容非法	    CE（Content Error）
 *        重复交易	    DO（Duplicate Operation）
 *        时间与期限	    TM（Time）
 *        风险控制     	RC（Risk Control）
 *        业务逻辑	    BL（Business Logic）
 *        不确定交易结果	NA（N/A）
 *        硬件错误	    HW（Hardware）
 *        数据内容相关	DC（Data Context）
 *        读写相关	    IO（I／O）
 *        数据库相关 	DB（Database）
 *        网络通讯    	NC（Network Communication）
 *        安全服务	    SS（Security Service）
 *        组件模块   	CM（Components or Modules）
 *        流量控制	    FC（Flow Control）
 *        重复交易	    DO（Duplicate Operation）
 *        技术逻辑	    TL（Technical Logic）
 *        纯技术性错误	AT（Absolute Technique）
 *        未实现的功能    NI (Not Implemented)
 * 第三段：长度为5位，用于对错误源进行分类和识别，内容填写出现错误的框架单元(物理组件)的对应编码
 *        框架逻辑单元、应用逻辑单元
 * 第四段：长度为4位，用于对错误的细分。对于某些种类的典型错误，可以使用一个专有的4位编号，这种处理方式由各应用(组件)自行定义
 *        从0000顺排
 * @author cmz
 */
public interface ErrorCodeEnum extends I18nMessageEnum {

    /**
     * 获取错误提示消息
     * @return 错误提示消息
     */
    @Override
    default String getMessage() {
        Locale locale;

        try {
            ProviderFactory providerFactory = SpringUtils.getBean(ProviderFactory.class);
            locale = providerFactory.getClientLocaleProvider().getLocale();
        } catch (Exception e) {
            locale = Locale.US;
        }

        return I18nUtils.get(locale, this.getBundle(), this.toString());
    }

}
